package com.beiding.my.bomapping;

import com.beiding.my.bemapping.BeFieldMapper;
import com.beiding.my.bemapping.BeTypeMapper;
import com.beiding.my.bemapping.BeTypeMapperHolder;
import com.beiding.my.common.BoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class BoTypeMapperHolder {


    private List<BoRepository> boRepositories;

    private BeTypeMapperHolder beTypeMapperHolder;

    public BoTypeMapperHolder(@Autowired(required = false) List<BoRepository> boRepositories, BeTypeMapperHolder beTypeMapperHolder) {
        this.boRepositories = boRepositories;
        this.beTypeMapperHolder = beTypeMapperHolder;
        try {

            //直接初始化
            init();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private Map<Class, BoTypeMapper> typeBoTypeMapperMap = new HashMap<>();
    private Map<String, BoTypeMapper> nameBoTypeMapperMap = new HashMap<>();

    public <T> BoTypeMapper<T> getBoTypeMapper(Class<T> type) {
        return typeBoTypeMapperMap.get(type);
    }

    public BoTypeMapper getBoTypeMapper(String name) {
        return nameBoTypeMapperMap.get(name);
    }


    private void init() throws Exception {

        for (BoRepository repository : boRepositories) {
            BoTypeMapper boTypeMapper = new BoTypeMapper();
            Class<? extends BoRepository> boRepositoryType = repository.getClass();

            String simpleName = boRepositoryType.getSimpleName();

            String boTypeName = simpleName.substring(0, simpleName.length() - 10);
            Class boType = Class.forName(boRepositoryType.getPackage().getName() + "." + boTypeName);

            boTypeMapper.type = boType;
            boTypeMapper.name = boTypeName;

            //获取到be实体的类型
            BeTypeMapper beTypeMapper = beTypeMapperHolder.getMapper(boTypeName + "Be");
            boTypeMapper.beTypeMapper = beTypeMapper;
            //带有泛型的就必须强转
            for (BeFieldMapper field : (List<BeFieldMapper>) beTypeMapper.getFields()) {
                BoFieldMapper boFieldMapper = new BoFieldMapper();
                boFieldMapper.beTypeMapper = beTypeMapper;
                boFieldMapper.name = field.getName();
                boFieldMapper.beFiled = boType.getDeclaredField("_be");
                boFieldMapper.beFiled.setAccessible(true);
                boTypeMapper.addAttributeMapper(boFieldMapper);
            }

            typeBoTypeMapperMap.put(boType, boTypeMapper);
            nameBoTypeMapperMap.put(boTypeName, boTypeMapper);
        }

        for (BoTypeMapper boTypeMapper : typeBoTypeMapperMap.values()) {

            Class boType = boTypeMapper.type;

            //现在还不能
            for (Field field : boType.getDeclaredFields()) {
                String name = field.getName();
                if (name.startsWith("_quote_")) {
                    name = name.substring(7);
                    field.setAccessible(true);
                    Class<?> type = field.getType();
                    BoQuoteMapper boQuoteMapper = new BoQuoteMapper();
                    boQuoteMapper.name = name;
                    boQuoteMapper.quoteFiled = field;
                    boQuoteMapper.realBoTypeMapper = typeBoTypeMapperMap.get(type);
                    boTypeMapper.addAttributeMapper(boQuoteMapper);
                }
            }
        }


    }
}
